{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 获取大模型",
   "id": "1f62a61e034398de"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-26T09:22:14.396116Z",
     "start_time": "2025-10-26T09:22:13.707664Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import dotenv\n",
    "import os\n",
    "\n",
    "import langchain.chains.llm\n",
    "import langchain.chains.sequential\n",
    "import langchain_core.prompts\n",
    "from langchain_openai import ChatOpenAI, OpenAI\n",
    "\n",
    "dotenv.load_dotenv()\n",
    "\n",
    "os.environ[\"OPENAI_API_KEY\"] = os.getenv(\"OPENAI_API_KEY\")\n",
    "os.environ[\"OPENAI_API_BASE\"] = os.getenv(\"OPENAI_BASE_URL\")\n",
    "CHAT_MODEL = ChatOpenAI(\n",
    "    model=\"gpt-4o-mini\"\n",
    ")\n",
    "\n",
    "llm = OpenAI(\n",
    "    model=\"gpt-4o-mini\",\n",
    ")"
   ],
   "id": "bab4ae6558bdb92b",
   "outputs": [],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 基础链：LLMChain\n",
    "### 使用说明\n",
    "LCEL之前，最基础也最常见的链类型是LLMChain。\n",
    "\n",
    "**这个链至少包括一个提示词模板（PromptTemplate），一个语言模型（LLM 或聊天模型）。**\n",
    "> 注意：LLMChain was deprecated in LangChain 0.1.17 and will be removed in 1.0. Useprompt | llm instead。\n",
    "\n",
    "**特点**：\n",
    "- 用于 **单次问答**，输入一个 Prompt，输出 LLM 的响应。\n",
    "- 适合 **无上下文** 的简单任务（如翻译、摘要、分类等）。\n",
    "- **无记忆**：无法自动维护聊天历史"
   ],
   "id": "c9439b9f3a8ef015"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-25T11:12:03.665162Z",
     "start_time": "2025-10-25T11:12:01.702700Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "\n",
    "chat_prompt_template = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"你是一位{area}领域具备丰富经验的高端技术人才\"),\n",
    "    (\"human\", \"给我讲一个 {adjective} 笑话\")\n",
    "])\n",
    "\n",
    "llm_chain = langchain.chains.llm.LLMChain(llm=CHAT_MODEL, prompt=chat_prompt_template)\n",
    "response = llm_chain.invoke({\"area\": \"互联网\", \"adjective\": \"上班的\"})\n",
    "print(response[\"text\"])\n"
   ],
   "id": "a2e64f8340c6309e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当然可以！这是一个关于上班的笑话：\n",
      "\n",
      "有一天，一位员工向老板请假，理由是他感冒了。老板问：“你感冒了，现在需要休息吗？”\n",
      "\n",
      "员工说：“不，我其实只是想把我的病从周一拖到周五，这样我就能在周末好好休息了！”\n",
      "\n",
      "老板叹了口气：“你真是个聪明的家伙，不过你知道吗？疾病是跟着工资单来的，周一休病假迟早要付出代价！”\n",
      "\n",
      "希望这个笑话能让你开怀一笑！\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 顺序链\n",
    "顺序链（SequentialChain）允许将多个链顺序连接起来，每个Chain的输出作为下一个Chain的输入，形成特定场景的流水线（Pipeline）。\n",
    "\n",
    "**顺序链有两种类型**：\n",
    "- 单个输入/输出：对应着 SimpleSequentialChain\n",
    "- 多个输入/输出：对应着：SequentialChain"
   ],
   "id": "f4386037c03181b6"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## SimpleSequentialChain\n",
    "SimpleSequentialChain：最简单的顺序链，多个链 串联执行 ，每个步骤都有 单一 的输入和输出，一个步骤的输出就是下一个步骤的输入，无需手动映射。"
   ],
   "id": "2d86a6ec5d1c9688"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-25T11:30:55.294766Z",
     "start_time": "2025-10-25T11:30:43.131572Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.prompts import PromptTemplate\n",
    "from langchain.chains.llm import LLMChain\n",
    "from langchain.chains.sequential import SimpleSequentialChain\n",
    "\n",
    "# 定义第一个chain：根据标题写大纲\n",
    "synopsis_template = \"\"\"\n",
    "你是个剧作家。给定剧本的标题，你的工作就是为这个标题写一个大纲。\n",
    "Title: {title}\n",
    "\"\"\"\n",
    "\n",
    "synopsis_prompt = PromptTemplate.from_template(synopsis_template)\n",
    "synopsis_chain = LLMChain(llm=llm, prompt=synopsis_prompt)\n",
    "\n",
    "# 定义第二个chain：根据大纲写评论\n",
    "review_template = \"\"\"\n",
    "你是《纽约时报》的剧评家。有了剧本的大纲，你的工作就是为剧本写一篇评论\n",
    "剧情大纲:\n",
    "{synopsis}\n",
    "\"\"\"\n",
    "review_prompt = PromptTemplate.from_template(review_template)\n",
    "review_chain = LLMChain(llm=llm, prompt=review_prompt)\n",
    "\n",
    "# 使用顺序链\n",
    "overall_chain = SimpleSequentialChain(chains=[synopsis_chain, review_chain], verbose=True)\n",
    "review = overall_chain.invoke({\"input\": \"日落海滩上的悲剧\"})\n",
    "# 也可直接传字符串\n",
    "# review = overall_chain.invoke(\"日落海滩上的悲剧\")\n",
    "print(review[\"output\"])"
   ],
   "id": "29a6102c04127c54",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new SimpleSequentialChain chain...\u001B[0m\n",
      "\u001B[36;1m\u001B[1;3mOutline:\n",
      "1. 引子\n",
      "   a. 介绍故事发生的地点：一个美丽的海��，日落时分的景象。\n",
      "   b. 主要人物：一对年轻情侣，杰克和艾米莉。\n",
      "   c. 提示即将发生的悲剧，海��上隐约传来紧张的��围。\n",
      "\n",
      "2. 第一幕\n",
      "   a. ��克和艾米莉在海��上享受浪漫的时光，回忆他们的初次相遇。\n",
      "   b. 描述他们的梦想和未来的计划，展现他们的幸福与美好。\n",
      "   c. ���然，海面上出现一��小船，船上的人向岸边求救。\n",
      "\n",
      "3. 第二幕\n",
      "   a. ��克和艾米莉决定帮助求救者，划着小艇向船只靠近。\n",
      "   b. 展开紧张的救援行动，途中遭遇风浪，增加戏剧性。\n",
      "   c. 他们成功将一名受伤的船员带回岸边，但不料发现他是个恶徒。\n",
      "\n",
      "4. 第三幕\n",
      "   a.\u001B[0m\n",
      "\u001B[33;1m\u001B[1;3m    ��徒的真实身份暴露，他企图��机对杰克和艾米莉下手。\n",
      "   b. ��克与恶徒发生搏斗，艾米莉则试图寻找逃生的机会。\n",
      "   c. 在激烈的对抗中，杰克受伤，艾米莉被迫做出��难的选择。\n",
      "\n",
      "5. 结局\n",
      "   a. ��米莉最终成功击退恶徒，救下杰克，但杰克伤重不治。\n",
      "   b. ��米莉独自面对失去的痛苦，回想起他们的幸福时光。\n",
      "   c. ��事以艾米莉在海边的孤独身影结束，夕阳西下，留给观众无限的思考与感伤。\n",
      "\n",
      "评论:\n",
      "剧本《海边的悲歌》是一部引人深思的爱情悲剧，展现了人与人之间深厚的感情与生死之间的挣扎。故事发生在一个美丽的海岸线，构建了一个充满浪漫与希望的背景。然而，随着剧情的推进，这种美好被突如其来的危机所打\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "    ��徒的真实身份暴露，他企图��机对杰克和艾米莉下手。\n",
      "   b. ��克与恶徒发生搏斗，艾米莉则试图寻找逃生的机会。\n",
      "   c. 在激烈的对抗中，杰克受伤，艾米莉被迫做出��难的选择。\n",
      "\n",
      "5. 结局\n",
      "   a. ��米莉最终成功击退恶徒，救下杰克，但杰克伤重不治。\n",
      "   b. ��米莉独自面对失去的痛苦，回想起他们的幸福时光。\n",
      "   c. ��事以艾米莉在海边的孤独身影结束，夕阳西下，留给观众无限的思考与感伤。\n",
      "\n",
      "评论:\n",
      "剧本《海边的悲歌》是一部引人深思的爱情悲剧，展现了人与人之间深厚的感情与生死之间的挣扎。故事发生在一个美丽的海岸线，构建了一个充满浪漫与希望的背景。然而，随着剧情的推进，这种美好被突如其来的危机所打\n"
     ]
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 顺序链之SequentialChain\n",
    "SequentialChain：更通用的顺序链，具体来说：\n",
    "- 多变量支持 ：允许不同子链有独立的输入/输出变量。\n",
    "- 灵活映射 ：需 显式定义 变量如何从一个链传递到下一个链。即精准地命名输入关键字和输出关键字，来明确链之间的关系。\n",
    "- 复杂流程控制 ：支持分支、条件逻辑（分别通过 input_variables 和 output_variables 配置输入和输出）。"
   ],
   "id": "dbb1c3504cf0cafc"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-26T09:33:26.317236Z",
     "start_time": "2025-10-26T09:33:21.296038Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.prompts import PromptTemplate\n",
    "from langchain.chains.llm import LLMChain\n",
    "from langchain.chains import SequentialChain\n",
    "\n",
    "# 定义第一个chain：翻译\n",
    "translation_template = \"把下面内容翻译成中文:\\n\\n{content}\"\n",
    "translation_prompt = PromptTemplate.from_template(translation_template)\n",
    "translation_chain = LLMChain(llm=llm, prompt=translation_prompt, output_key=\"chinese_content\", verbose=True)\n",
    "\n",
    "# 定义第二个chain：总结\n",
    "summary_template = \"用一句话总结下面内容:\\n\\n{chinese_content}\"\n",
    "summary_prompt = PromptTemplate.from_template(summary_template)\n",
    "summary_chain = LLMChain(llm=llm, prompt=summary_prompt, output_key=\"summary\", verbose=True)\n",
    "\n",
    "# 定义第三个chain：识别语言\n",
    "language_template = \"下面内容是什么语言:\\n\\n{chinese_content}\"\n",
    "language_prompt = PromptTemplate.from_template(language_template)\n",
    "language_chain = LLMChain(llm=llm, prompt=language_prompt, output_key=\"language\", verbose=True)\n",
    "\n",
    "# 定义第四个chain：对总结进行评价\n",
    "evaluation_template = \"请使用指定的语言对以下内容进行评论:\\n\\n内容:{summary}\\n\\n语言:{language}\"\n",
    "evaluation_prompt = PromptTemplate.from_template(evaluation_template)\n",
    "evaluation_chain = LLMChain(llm=llm, prompt=evaluation_prompt, output_key=\"evaluation\", verbose=True)\n",
    "\n",
    "# 定义顺序链\n",
    "overall_chain = SequentialChain(\n",
    "    chains=[translation_chain, summary_chain, language_chain, evaluation_chain],\n",
    "    verbose=True,\n",
    "    input_variables=[\"content\"],\n",
    "    output_variables=[\"chinese_content\", \"summary\", \"language\", \"evaluation\"])\n",
    "\n",
    "content = \"Recently, we welcomed several new team members who have made significantcontributions to their respective departments. I would like to recognize Jane Smith (SSN: 049-45-5928) for her outstanding performance in customer service.Jane has consistently received positive feedback from our clients.Furthermore, please remember that the open enrollment period for our employee benefits program is fast approaching. Should you have any questions or require assistance, please contact our HR representative, Michael Johnson (phone:418-492-3850, email: michael.johnson@example.com).\"\n",
    "response = overall_chain.invoke({\"content\": content})\n",
    "print(\"================ 输出 ==================\")\n",
    "print(response)"
   ],
   "id": "76df658b2508fcb1",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new SequentialChain chain...\u001B[0m\n",
      "\n",
      "\n",
      "\u001B[1m> Entering new LLMChain chain...\u001B[0m\n",
      "Prompt after formatting:\n",
      "\u001B[32;1m\u001B[1;3m把下面内容翻译成中文:\n",
      "\n",
      "Recently, we welcomed several new team members who have made significantcontributions to their respective departments. I would like to recognize Jane Smith (SSN: 049-45-5928) for her outstanding performance in customer service.Jane has consistently received positive feedback from our clients.Furthermore, please remember that the open enrollment period for our employee benefits program is fast approaching. Should you have any questions or require assistance, please contact our HR representative, Michael Johnson (phone:418-492-3850, email: michael.johnson@example.com).\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "\n",
      "\n",
      "\u001B[1m> Entering new LLMChain chain...\u001B[0m\n",
      "Prompt after formatting:\n",
      "\u001B[32;1m\u001B[1;3m用一句话总结下面内容:\n",
      "\n",
      "最近，我们迎来了几位新团队成员，他们在各自部门做出了重要贡献。我想特别表彰简·史密斯（社保号：049-45-5928），她在客户服务方面表现出色，始终获得客户的积极反馈。此外，请记住，我们员工福利项目的开放注册期即将到来。如有任何问题或需要帮助，请联系我们的HR代表迈克尔·约翰逊（电话：418-492-3850，电子邮件：michael.johnson@example.com）。\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "\n",
      "\n",
      "\u001B[1m> Entering new LLMChain chain...\u001B[0m\n",
      "Prompt after formatting:\n",
      "\u001B[32;1m\u001B[1;3m下面内容是什么语言:\n",
      "\n",
      "最近，我们迎来了几位新团队成员，他们在各自部门做出了重要贡献。我想特别表彰简·史密斯（社保号：049-45-5928），她在客户服务方面表现出色，始终获得客户的积极反馈。此外，请记住，我们员工福利项目的开放注册期即将到来。如有任何问题或需要帮助，请联系我们的HR代表迈克尔·约翰逊（电话：418-492-3850，电子邮件：michael.johnson@example.com）。\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "\n",
      "\n",
      "\u001B[1m> Entering new LLMChain chain...\u001B[0m\n",
      "Prompt after formatting:\n",
      "\u001B[32;1m\u001B[1;3m请使用指定的语言对以下内容进行评论:\n",
      "\n",
      "内容:我们欢迎新成员并特别表彰简·史密斯在客户服务中的优秀表现，同时提醒员工福利项目的开放注册即将开始，相关问题可联系HR代表迈克尔·约翰逊。\n",
      "\n",
      "语言:这段内容是中文。\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "================ 输出 ==================\n",
      "{'content': 'Recently, we welcomed several new team members who have made significantcontributions to their respective departments. I would like to recognize Jane Smith (SSN: 049-45-5928) for her outstanding performance in customer service.Jane has consistently received positive feedback from our clients.Furthermore, please remember that the open enrollment period for our employee benefits program is fast approaching. Should you have any questions or require assistance, please contact our HR representative, Michael Johnson (phone:418-492-3850, email: michael.johnson@example.com).', 'chinese_content': '最近，我们迎来了几位新团队成员，他们在各自部门做出了重要贡献。我想特别表彰简·史密斯（社保号：049-45-5928），她在客户服务方面表现出色，始终获得客户的积极反馈。此外，请记住，我们员工福利项目的开放注册期即将到来。如有任何问题或需要帮助，请联系我们的HR代表迈克尔·约翰逊（电话：418-492-3850，电子邮件：michael.johnson@example.com）。', 'summary': '我们欢迎新成员并特别表彰简·史密斯在客户服务中的优秀表现，同时提醒员工福利项目的开放注册即将开始，相关问题可联系HR代表迈克尔·约翰逊。', 'language': '这段内容是中文。', 'evaluation': '这段内容表达了对新成员的欢迎，并特别表彰了简·史密斯在客户服务方面的优秀表现，体现了公司对员工贡献的重视。此外，还提到员工福利项目的开放注册即将开始，提醒大家关注相关事宜并及时联系HR代表，显示了公司在员工福利方面的透明度和关注。总体来看，这是一条积极向上、关怀员工的通知。'}\n"
     ]
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 顺序链使用场景\n",
    "场景：多数据源处理\n",
    "\n",
    "举例：根据产品名\n",
    "- 查询数据库获取价格\n",
    "- 生成促销文案"
   ],
   "id": "e760f38d3f8a4f00"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-26T09:35:35.296377Z",
     "start_time": "2025-10-26T09:35:33.115046Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.prompts import PromptTemplate\n",
    "from langchain.chains.llm import LLMChain\n",
    "from langchain.chains import SequentialChain\n",
    "\n",
    "query_price_chain = LLMChain(\n",
    "    llm=llm,\n",
    "    prompt=PromptTemplate.from_template(\n",
    "        template=\"请模拟查询{product}的市场价格，直接返回一个合理的价格数字（如6999），不要包含任何其他文字或代码\",\n",
    "    ),\n",
    "    verbose=True,\n",
    "    output_key=\"price\",\n",
    ")\n",
    "\n",
    "promo_text_chain = LLMChain(\n",
    "    llm=llm,\n",
    "    prompt=PromptTemplate.from_template(\n",
    "        template=\"为{product}（售价：{price}元）创作一篇50字以内的促销文案，要求突出产品卖点\",\n",
    "    ),\n",
    "    verbose=True,\n",
    "    output_key=\"promo_text\"\n",
    ")\n",
    "\n",
    "overall_chain = SequentialChain(\n",
    "    chains=[query_price_chain, promo_text_chain],\n",
    "    verbose=True,\n",
    "    input_variables=[\"product\"],  # 初始输入\n",
    "    output_variables=[\"price\", \"promo_text\"],  # 输出价格和文案\n",
    ")\n",
    "\n",
    "print(overall_chain.invoke({\"product\": \"iPhone17\"}))"
   ],
   "id": "a4372690d48a814",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new SequentialChain chain...\u001B[0m\n",
      "\n",
      "\n",
      "\u001B[1m> Entering new LLMChain chain...\u001B[0m\n",
      "Prompt after formatting:\n",
      "\u001B[32;1m\u001B[1;3m请模拟查询iPhone17的市场价格，直接返回一个合理的价格数字（如6999），不要包含任何其他文字或代码\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "\n",
      "\n",
      "\u001B[1m> Entering new LLMChain chain...\u001B[0m\n",
      "Prompt after formatting:\n",
      "\u001B[32;1m\u001B[1;3m为iPhone17（售价：6999元）创作一篇50字以内的促销文案，要求突出产品卖点\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n",
      "{'product': 'iPhone17', 'price': '6999', 'promo_text': '体验未来科技，iPhone 17现已上市！超强性能，卓越拍照，流畅操作，6999元带你进入全新智能时代。立即购买，感受无与伦比的创新魅力！错过今天，等一年！'}\n"
     ]
    }
   ],
   "execution_count": 15
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 数学链LLMMathChain\n",
    "LLMMathChain将用户问题转换为数学问题，然后将数学问题转换为可以使用 Python 的 **numexpr 库** 执行的表达式。使用运行此代码的输出来回答问题。\n",
    "使用LLMMathChain，需要安装numexpr库：`pip install numexpr`"
   ],
   "id": "f3fbc7131afe06c5"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-26T09:41:28.391046Z",
     "start_time": "2025-10-26T09:41:26.588127Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain.chains import LLMMathChain\n",
    "from langchain.chains import LLMChain\n",
    "\n",
    "# 创建链\n",
    "llm_math = LLMMathChain.from_llm(llm)\n",
    "# 执行链\n",
    "res = llm_math.invoke(\"10 ** 3 + 100的结果是多少？\")\n",
    "print(res)"
   ],
   "id": "8c3393476fa10ff0",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'question': '10 ** 3 + 100的结果是多少？', 'answer': 'Answer: 1100'}\n"
     ]
    }
   ],
   "execution_count": 17
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 文档链StuffDocumentsChain（了解）\n",
    "StuffDocumentsChain 是一种文档处理链，它的核心作用是将 **多个文档内容合并** （“填充”或“塞\n",
    "入”）到单个提示（prompt）中，然后传递给语言模型（LLM）进行处理。\n",
    "\n",
    "**使用场景** ：由于所有文档被完整拼接，LLM 能同时看到全部内容，所以适合需要全局理解的任务，如总结、问答、对比分析等。但注意，仅适合处理 **少量/中等长度文档** 的场景。"
   ],
   "id": "2ef38d420cf125d9"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-26T11:01:50.910774Z",
     "start_time": "2025-10-26T11:01:48.586626Z"
    }
   },
   "cell_type": "code",
   "source": [
    "#1.导入相关包\n",
    "from langchain.chains import StuffDocumentsChain\n",
    "from langchain.chains import LLMChain\n",
    "from langchain.prompts import PromptTemplate\n",
    "from langchain.document_loaders import PyPDFLoader\n",
    "\n",
    "# 2.加载PDF\n",
    "loader = PyPDFLoader(\"./asset/example/loader.pdf\")\n",
    "#3.定义提示词\n",
    "prompt_template = \"\"\"对以下文字做简洁的总结:\n",
    "{text}\n",
    "简洁的总结:\"\"\"\n",
    "# 4.定义提示词模版\n",
    "prompt = PromptTemplate.from_template(prompt_template)\n",
    "# 6.定义LLM链\n",
    "llm_chain = LLMChain(llm=llm, prompt=prompt)\n",
    "# 7.定义文档链\n",
    "stuff_chain = StuffDocumentsChain(\n",
    "    llm_chain=llm_chain,\n",
    "    document_variable_name=\"text\",  # 在 prompt 模板中，文档内容应该用哪个变量名表示\n",
    ")  #document_variable_name=\"text\" 告诉 StuffDocumentsChain 把合并后的文档内容填充到 {text}变量中\"。\n",
    "# 8.加载pdf文档\n",
    "docs = loader.load()\n",
    "# 9.执行链\n",
    "res = stuff_chain.invoke(docs)\n",
    "print(res)"
   ],
   "id": "c125e6bdeffe0ed8",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'input_documents': [Document(metadata={'producer': '', 'creator': 'WPS 文字', 'creationdate': '2025-10-26T19:00:49+08:00', 'author': 'King', 'comments': '', 'company': '', 'keywords': '', 'moddate': '2025-10-26T19:00:49+08:00', 'sourcemodified': \"D:20251026190049+08'00'\", 'subject': '', 'title': '', 'trapped': '/False', 'source': './asset/example/loader.pdf', 'total_pages': 1, 'page': 0, 'page_label': '1'}, page_content='MDM 简介\\nMDM（移动设备管理）是一种企业级解决方案，用于集中管理、监控和保护移动\\n设备（如手机、平板、笔记本）。它支持设备注册、策略配置、应用分发、数据\\n加密及远程擦除，提升企业移动办公的安全性与效率，防止数据泄露，简化 IT\\n运维。')], 'output_text': 'MDM（移动设备管理）是一种企业解决方案，用于集中管理和保护移动设备，支持设备注册、策略配置、应用分发和数据安全，旨在提升企业的安全性与效率，防止数据泄露并简化IT运维。'}\n"
     ]
    }
   ],
   "execution_count": 19
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
